<?php
/**
 * MarcWriter class for write MarcRecord objects to file or string
 * @author Sergey Dostovalov
 */
class MarcWriter{
    const SOURCE_FILE = 1;
    const SOURCE_STRING = 2;

    const MODE_WRITE_NEW = 3;
    const MODE_WRITE_TO_END = 4;

    private $file = null; //file handler to write
    private $sourceOut = null;
    private $toEncoding = null;
    /**
     *
     * @param integer $sourceOut MarcWriter::SOURCE_FILE or MarcWriter::SOURCE_STRING
     * @param string  $filename if sourceOut is file
     * @param int $mode MarcWriter::MODE_WRITE_NEW or MODE_WRITE_TO_END. Default MODE_WRITE_NEW
     * @param string $toEncoding of result file. Default UTF-8
     * @exception Exception
     */
    public function  __construct($sourceOut, $filename = null , $mode = self::MODE_WRITE_NEW, $toEncoding = null) {
        $this->sourceOut = $sourceOut;
        $this->toEncoding = $toEncoding;
        if($sourceOut === self::SOURCE_FILE){
            $openMode = '';
            if($mode === self::MODE_WRITE_NEW) $openMode = 'w';
            if($mode === self::MODE_WRITE_TO_END) $openMode = 'w+';
            if ($filename === null) throw new Exception('No filename of out source');
            if(!$this->file = @fopen($filename, $openMode)){
                throw new Exception('File '.$filename.' can\'t open for write');
            }
        }
    }
    
    public function  __destruct() {
        if ($this->file !== null) fclose($this->file);
    }
    /**
     *
     * @param MarcRecord $record
     * @exception Exception
     */
    public function writeRecord(MarcRecord $record){
        if($this->sourceOut === self::SOURCE_FILE){
            try{
                $this->writeToFile($record->toRaw($this->toEncoding));
            }
            catch(Exception $e){
                throw $e;
            }
        }
        if($this->sourceOut === self::SOURCE_STRING){
            return $record->toRaw($this->toEncoding);
        }
    }/**
     *
     * @param array $records array of MarcRecord objects
     * @exception Exception
     */
    public function writeRecords(array $records){
        $rawRecords = array();
        foreach($records as $record){
            if($this->sourceOut === self::SOURCE_FILE){
                try{
                    $this->writeToFile($record->toRaw($this->toEncoding));
                }
                catch(Exception $e){
                    throw $e;
                }
            }
            if($this->sourceOut === self::SOURCE_STRING){
                $rawRecords[] = $record->toRaw($this->toEncoding);
            }
        }
        if($this->sourceOut === self::SOURCE_STRING){
                return join('', $rawRecords);
        }
    }
    /**
     * @param string $raw raw marc recors
     * @exception Exception
     */
    private function writeToFile(&$raw){
        if (fwrite($this->file, $raw) === false){
            throw new Exception('Error of write to file ');
        }
    }
}
?>
